﻿using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using Ionic.Zip;

namespace Commands
{
    class Zipper
    {
        internal static void UnzipFolder(string folderPath)
        {
            if(Directory.Exists(folderPath))
            {
                var di = new DirectoryInfo(folderPath);
                foreach (var file in di.EnumerateFiles().Where(x => _FileIsZip(x)))
                {
                    _ExtractZip(file, folderPath);
                    File.Delete(file.FullName);
                }
            }
        }

        private static void _ExtractZip(FileInfo file, string folderPath)
        {
            using (ZipFile zip1 = Ionic.Zip.ZipFile.Read(file.FullName))
            {
                // here, we extract every entry, but we could extract conditionally
                // based on entry name, size, date, checkbox status, etc.  
                foreach (ZipEntry e in zip1)
                {
                    e.Extract(folderPath, ExtractExistingFileAction.OverwriteSilently);
                }
            }
        }

        private static bool _FileIsZip(FileInfo x)
        {
            return x.Extension == ZIP_EXTENSION;
        }

        internal static List<string> ZipFile(string filePath, int size, string password)
        {
            return _Zip(null, filePath, size, password);
        }

        internal static List<string> ZipFolder(string directory, int size, string password)
        {
            return _Zip(directory, null, size, password);
        }

        internal static string ZipFolder(string directory)
        {
            return _Zip(directory, null, null, null).First();
        }

        private static List<string> _Zip(string directory, string filePath, int? size, string password)
        {
            var dirInfo = new DirectoryInfo(directory);
            var zipName = FilesHelper.PrepareTempZipFilePath(dirInfo.Name);

            using (ZipFile zip = new ZipFile())
            {
                zip.AlternateEncoding = Encoding.UTF8;  
                zip.UseZip64WhenSaving = Zip64Option.AsNecessary;
                zip.AlternateEncodingUsage = ZipOption.AsNecessary;

                if (size > 0)
                    zip.MaxOutputSegmentSize = (int)size;

                if (!string.IsNullOrEmpty(password))
                { 
                   zip.Password = password;
                   zip.Encryption = EncryptionAlgorithm.WinZipAes128;
                }

                if (!string.IsNullOrEmpty(directory))
                    zip.AddDirectory(directory);

                if (!string.IsNullOrEmpty(filePath))
                    zip.AddFile(filePath);

                zip.Comment = "This zip was created at " + System.DateTime.Now.ToString("G") ;

                zip.Save(zipName);
            }

            return _ListAllZipFiles(zipName);
        }

        private static List<string> _ListAllZipFiles(string zipName)
        {
            var fileInfo = new FileInfo(zipName);

            var result = new List<string>();
            foreach (var file in fileInfo.Directory.EnumerateFiles())
                result.Add(file.FullName);

            return result;
        }

        private static string ZIP_EXTENSION = ".zip";

        //private static void _CheckSize(string directoryName, int size)
        //{
        //    if (_GetDirectorySize(directoryName) / size > 99)
        //        throw NotSupportedException
        //}


        //private static long _GetDirectorySize(string directoryName)
        //{
        //    // 1
        //    // Get array of all file names.
        //    string[] a = Directory.GetFiles(p, "*.*");

        //    // 2
        //    // Calculate total bytes of all files in a loop.
        //    long b = 0;
        //    foreach (string name in a)
        //    {
        //        // 3
        //        // Use FileInfo to get length of each file.
        //        FileInfo info = new FileInfo(name);
        //        b += info.Length;
        //    }
        //    // 4
        //    // Return total size
        //    return b;
        //}


    }
}